package com.binarycat.dynamiclimit.util;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.context.ApplicationContext;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import com.binarycat.dynamiclimit.DynamicLimiterManager;
import com.binarycat.dynamiclimit.annotation.DynamicLimit;
import com.binarycat.dynamiclimit.constant.CommonLimitConstants;

import cn.hutool.http.HttpUtil;

/**
 * 通用的限流工具类
 * 
 * @author jjb
 * @date 2018/08/16
 */
public class CommonLimitUtils {

    /**
     * 根据Ip隔离获取对应的key
     * 
     * @param method
     * @param request
     * @return
     */
    public static String getKeyByIpQuarantine(HandlerMethod method, HttpServletRequest request) {
        String ip = HttpUtil.getClientIP(request);
        StringBuilder ipkey = new StringBuilder();
        ipkey.append(CommonLimitConstants.PREFIX_METRIC_KEY_IP);
        ipkey.append(ip);
        ipkey.append(":");
        ipkey.append(method.toString());
        return ipkey.toString();
    }

    /**
     * 创建锁
     * 
     * @param classObj
     * @return
     */
    public static String getLock(Class<?> classObj) {
        return new String(classObj.getName());
    }

    /**
     * 获取该方法上的限流注解
     * 
     * @param method
     * @return
     */
    public static DynamicLimit getDynamicLimitAnnotation(HandlerMethod handlerMethod) {
        DynamicLimit classDynamicLimit = handlerMethod.getBeanType().getAnnotation(DynamicLimit.class);
        DynamicLimit methodDynamicLimit = handlerMethod.getMethodAnnotation(DynamicLimit.class);
        return methodDynamicLimit == null ? classDynamicLimit : methodDynamicLimit;

    }

    /**
     * @param dynamicLimiterManager
     * @return
     */
    public static Map<RequestMappingInfo, HandlerMethod>
        getHandlerMethodMap(DynamicLimiterManager dynamicLimiterManager) {
        ApplicationContext applicationContext = dynamicLimiterManager.getApplicationContext();
        RequestMappingHandlerMapping requestMappingHandlerMapping =
            applicationContext.getBean(RequestMappingHandlerMapping.class);

        Map<RequestMappingInfo, HandlerMethod> handlerMethodMap = requestMappingHandlerMapping.getHandlerMethods();
        return handlerMethodMap;
    }
}
